﻿using Microsoft.AspNetCore.Http;
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Lynn.Infastructure.Aop.Model;
using Lynn.Infastructure.Aop.Attributes;
using Lynn.Infastructure.Utils;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;

namespace Lynn.Infastructure.Aop.Middleware
{
    public class ResultMiddleware
    {
        private readonly RequestDelegate _next;
        public ResultMiddleware(RequestDelegate next)
        {
            _next = next;
        }
        public async Task Invoke(HttpContext context)
        {
            if (context.GetEndpoint()?.Metadata?.GetMetadata<NotWrapResultAttribute>()is NotWrapResultAttribute notWrapResult)            
            {
                await _next(context);
                return;
            }
            var originalBodyStream = context.Response.Body;
            {
                using var responseBody = new MemoryStream();
                context.Response.Body = responseBody;
                var msg = new Msg();
                try
                {
                    await _next(context);
                    var result = await FormatResponse(context.Response);
                    msg.Code = context.Response.StatusCode;
                    msg.Data = result;
                }
                catch (Error ex)
                {
                    msg.Message = ex.Message;
                    msg.Code = 500;
                }
                catch (DbUpdateConcurrencyException ex) {
                    var x = ex;
                    LogerHelper.Error($"数据修改错误=>{context.Request.Path}", ex);
                    msg.Message = "修改失败,当前数据已在其他地方修改";
                    msg.Code = 500;
                }
                catch (Exception ex)
                {
                    LogerHelper.Error($"系统错误=>{context.Request.Path}", ex);
                    //msg.Message = "系统错误";
                    msg.Message = $"{ex.Message}:{ex.StackTrace}";
                    msg.Code = 500;
                }
                if (msg.Code == 404)
                {
                    msg.Message = "您访问的路径不存在";
                }
                //204消息不响应
                if (msg.Code == 204)
                {
                    return;
                }
                context.Response.ContentType = "application/json; charset=utf-8";
                var json = JsonNtHelper.ObjectToJson(msg);
                byte[] array = Encoding.UTF8.GetBytes(json);
                context.Response.ContentLength = array.Length;
                MemoryStream stream = new MemoryStream(array);
                await stream.CopyToAsync(originalBodyStream);
            }
        }
        private async Task<object> FormatResponse(HttpResponse response)
        {
            response.Body.Seek(0, SeekOrigin.Begin);
            var text = await new StreamReader(response.Body).ReadToEndAsync();
            response.Body.Seek(0, SeekOrigin.Begin);
            var obj = JsonNtHelper.JsonToObject<object>(text);
            return obj ?? text;
        }
    }

}
